package testTransfoUML2Java;


import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.util.Iterator;

import org.eclipse.emf.common.util.EList;
import org.eclipse.uml2.uml.Class;
import org.eclipse.uml2.uml.Classifier;
import org.eclipse.uml2.uml.Interface;
import org.eclipse.uml2.uml.Operation;
import org.eclipse.uml2.uml.Type;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

import uml2Java.JavaChargeur;
import uml2Java.TransformMethods;
import uml2Java.TransformPackagesAndTypes;
import uml2Java.UMLChargeur;
import astjava.AbstractTypeDeclaration;
import astjava.BodyDeclaration;
import astjava.ClassDeclaration;
import astjava.InheritanceKind;
import astjava.InterfaceDeclaration;
import astjava.JavaFactory;
import astjava.MethodDeclaration;

public class TestTransformMethods {

	private static org.eclipse.uml2.uml.Package _umlPackage;
	
	private static astjava.Model _javaModel;
	
	private static TransformPackagesAndTypes _transformerTypes;

	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
		_javaModel = JavaFactory.eINSTANCE.createModel();
		UMLChargeur chargeur = new UMLChargeur("modele_de_test/testMethod.uml");
		_umlPackage = chargeur.loadUMLPackage();
		
		_transformerTypes = new TransformPackagesAndTypes(_umlPackage, _javaModel);
		_transformerTypes.doTransformPackagesAndTypes();
		TransformMethods transformerMethods = new TransformMethods(_transformerTypes);
		transformerMethods.doTransformMethods();
	}

	@Test
	public void testMethodsInInterface() {
		InterfaceDeclaration javaInterface = (InterfaceDeclaration) _transformerTypes.get_symbolMap().get("Interface");
		assertTrue(javaInterface.getBodyDeclarations().size()==2);
	}
	
	@Test
	public void testMethodsWithoutParametersList() {
		for (Type umlType : _umlPackage.getOwnedTypes()) {
			if (umlType instanceof Class || umlType instanceof Interface) {
				Classifier umlClassifier = (Classifier) umlType;
				astjava.AbstractTypeDeclaration javaType = (AbstractTypeDeclaration) _transformerTypes.get_symbolMap().get(umlClassifier.getName());
				EList<Operation> umlOperations = umlClassifier.getOperations();
				EList<BodyDeclaration> javaOperations = javaType.getBodyDeclarations();
				Iterator<Operation> iUmlOperations = umlOperations.iterator();
				Iterator<BodyDeclaration> iJavaOperations = javaOperations.iterator();
				while (iUmlOperations.hasNext()) {
					Operation umlOperation = iUmlOperations.next();
					BodyDeclaration javaBodyDeclaration = iJavaOperations.next();
					MethodDeclaration javaOperation = (MethodDeclaration) javaBodyDeclaration;
					assertEquals(umlOperation.getName(), javaOperation.getName());
					assertEquals(umlOperation.isStatic(), javaOperation.getModifier().isStatic());
					assertEquals(umlOperation.isAbstract(), javaOperation.getModifier().getInheritance().equals(InheritanceKind.ABSTRACT));
					if (umlOperation.getType()!=null) 
						assertEquals(_transformerTypes.get_symbolMap().get(umlOperation.getType().getName()), javaOperation.getReturnType().getType());
					else
						assertEquals(_transformerTypes.get_symbolMap().get("EVoid"), javaOperation.getReturnType().getType());
				}
			}
		}
	}
	
	@Test
	public void testParameters() {
		ClassDeclaration javaClass = (ClassDeclaration) _transformerTypes.get_symbolMap().get("ClassParametre");
		
		MethodDeclaration javaOperation1 = (MethodDeclaration) javaClass.getBodyDeclarations().get(0);
		assertTrue(javaOperation1.getParameters().size()==1);
		
		MethodDeclaration javaOperation2 = (MethodDeclaration) javaClass.getBodyDeclarations().get(1);
		assertTrue(javaOperation2.getParameters().size()==2);
		
		MethodDeclaration javaOperation3 = (MethodDeclaration) javaClass.getBodyDeclarations().get(2);
		assertTrue(javaOperation3.getParameters().size()==3);
		
		MethodDeclaration javaOperation4 = (MethodDeclaration) javaClass.getBodyDeclarations().get(3);
		assertTrue(javaOperation4.getParameters().size()==1);
		
	}

	
	@AfterClass
	public static void tearDownAfterClass() throws Exception {
		JavaChargeur chargeur = new JavaChargeur("modele_de_test/testMethod.astjava");
		chargeur.save(_javaModel);
	}
}
